package com.fengxu.gamescript.ui.main.mode.file

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter
import com.fengxu.gamescript.R
import com.fengxu.gamescript.data.GlobalData
import com.fengxu.gamescript.data.ScriptProp
import com.fengxu.gamescript.jsengine.core.JsRuntime
import com.fengxu.gamescript.ui.edit.EditActivity
import com.fengxu.gamescript.util.CommonUtils
import com.xuexiang.xui.adapter.simple.XUISimpleAdapter
import com.xuexiang.xui.utils.DensityUtils
import com.xuexiang.xui.widget.popupwindow.popup.XUIListPopup
import com.xuexiang.xui.widget.toast.XToast
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.sdk27.coroutines.onClick
import org.jetbrains.anko.sdk27.coroutines.onLongClick
import org.jetbrains.anko.toast
import java.io.File

class FileListAdapter: Adapter<FileListAdapter.ViewHolder>{

    // 上下文
    private var context: Context

    // 脚本文件列表
    var scriptFileList: MutableList<ScriptProp>


    /**
     * 脚本列表子项ViewHolder
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        // 根布局View
        val rootView: View by lazy { view.findViewById(R.id.file_item_root) }
        // 文件名组件
        val fileNameView: TextView by lazy { view.findViewById(R.id.file_item_name) }
        // 文件大小组件
        val fileSizeView: TextView by lazy { view.findViewById(R.id.file_item_size) }
        // 文件类型组件
        val fileTypeView: TextView by lazy { view.findViewById(R.id.file_item_type) }
        // 运行按钮
        val runBtn: ImageButton by lazy { view.findViewById(R.id.file_item_run) }
        // 编辑按钮
        val editBtn: ImageButton by lazy { view.findViewById(R.id.file_item_edit) }
        // 删除按钮
        val delBtn: ImageButton by lazy { view.findViewById(R.id.file_item_del) }
    }

    constructor(ctx: Context, fileList:MutableList<ScriptProp>){
        this.context = ctx
        this.scriptFileList = fileList
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        var view = LayoutInflater.from(parent.context).inflate(R.layout.file_item,parent,false)
        return ViewHolder(view)
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // 设置属性
        holder.fileNameView.text = scriptFileList[position].name
        holder.fileTypeView.text = scriptFileList[position].type
        val fileSize: Long = scriptFileList[position].size
        when{
            fileSize >= 1024 -> holder.fileSizeView.text = String.format("%.2f",fileSize / 1024.0) + " kb"
            fileSize >= 1024*1024 -> holder.fileSizeView.text = String.format("%.2f",fileSize /1024 / 1024.0) + " mb"
            fileSize >= 1024*1024*1024 -> holder.fileSizeView.text = String.format("%.2f",fileSize/1024/1024/1024.0) + " kb"
            else -> holder.fileSizeView.text = "$fileSize b"
        }
        // 添加事件
        holder.run {
            // 创建选项popup框
            val yScreen = DensityUtils.getScreenSize(true).y
            val itemList = arrayOf("重命名脚本","运行脚本","编辑脚本","删除脚本","终止脚本")
            val adapter = XUISimpleAdapter.create(context, itemList)
            val xuiListPopup =  XUIListPopup<Nothing>(context,adapter).apply {
                create(DensityUtils.dp2px(200F), DensityUtils.dp2px(210F)) {
                        parent, view, index, id ->
                    // 执行指定的选项功能
                    when (index){
                        0 -> renameScriptFile(position)
                        1 -> runScript(position)
                        2 -> openEdit(position)
                        3 -> deleteFile(position)
                        4 -> stopScript(position)
                    }
                    dismiss()
                }
                setHasDivider(true)
            }
            // 长按弹出选项popup
            rootView.onLongClick {
                val location:IntArray = arrayOf(0, 0).toIntArray()
                rootView.getLocationOnScreen(location)
                val yPos = location[1]
                if(yPos > yScreen / 2){
                    xuiListPopup.showUp(rootView)
                }else{
                    xuiListPopup.showDown(rootView)
                }
            }
            rootView.onClick { openEdit(position) }
            editBtn.onClick {  openEdit(position) }
            runBtn.onClick { runScript(position) }
            // 删除服务
            delBtn.onClick { deleteFile(position) }
        }
    }

    /**
     * 重命名脚本文件
     * @param position 脚本文件所处在列表中的位置
     */
    private fun renameScriptFile(position: Int){
        val file = File(scriptFileList[position].path)
        if(!file.exists() || !file.isFile){
            scriptFileList.removeAt(position)
            notifyItemRemoved(position)
        }else{
            CommonUtils.inputDialog(context,title = "重命名文件",hint = "文件名",content = "请输入新的文件名",
            onPositive = {
                val newFile = File(GlobalData.MusicScriptFolderPath + "/${it}.js")
                if(!newFile.exists()){
                    file.renameTo(newFile)
                    scriptFileList[position] = ScriptProp.getScriptByFile(newFile)
                    notifyItemChanged(position)
                }else{
                    XToast.error(context,"重命名失败，已有同名文件存在!").show()
                }
            })
        }
        notifyDataSetChanged()
    }

    /**
     * 打开脚本编辑器
     * @param position 脚本文件所处在列表中的位置
     */
    private fun openEdit(position: Int){
        if(!detectFileIsExist(position)) return
        val intent = Intent(context, EditActivity::class.java)
        intent.setData(Uri.fromFile(File(scriptFileList[position].path)))
        context.startActivity(intent)
    }

    /**
     * 运行脚本
     * @param position 脚本文件所处在列表中的位置
     */
    private fun runScript(position: Int){
        if(!detectFileIsExist(position)) return
        // 获取文件路径，开始执行脚本
        val file = File(scriptFileList[position].path)
        val runtimeName = file.name
        if(GlobalData.getRunningScriptMap().containsKey(runtimeName)){
            // 脚本已经在运行了
            XToast.warning(context,"该脚本已经在运行中，不可重复运行!").show()
        }else{
            // 运行脚本
            var jsRuntime = JsRuntime(file.name, context, file.readText())
            jsRuntime.start()
            XToast.success(context,"开始运行:${runtimeName}!").show()
        }

    }

    /**
     * 强行终止该脚本
     * @param 脚本文件所处在列表中的位置
     */
    private fun stopScript(position: Int){
        val name = scriptFileList[position].name
        if(GlobalData.getRunningScriptMap().containsKey(name)){
            // 强制停止运行
            GlobalData.getRunningScriptMap()[name]?.forceExit()
            XToast.success(context,"成功停止:${name}!").show()
        }else{
            XToast.warning(context,"该脚本并未运行!").show()
        }
    }


    /**
     * 删除脚本文件
     * @param pos 脚本在列表中的位置
     */
    private fun deleteFile(pos: Int){
        CommonUtils.toastDialog(context,title = "警告",
                content = "您将删除脚本:\"${scriptFileList[pos].name}\" ,是否继续?",
                onPositive = {
                    val file = File(scriptFileList[pos].path)
                    if(file.exists()){
                        file.delete()
                    }
                    scriptFileList.removeAt(pos)
                    notifyItemRemoved(pos)
                    notifyDataSetChanged()
                }
        )
    }

    /**
     * 检测脚本文件是否存在于,不存在则从列表中删除，并更新列表
     * @param position 脚本文件所处在列表中的位置
     * @return 返回文件可用
     */
    private fun detectFileIsExist(position: Int) : Boolean{
        val file = File(scriptFileList[position].path)
        if(!file.exists() || !file.isFile){
            scriptFileList.removeAt(position)
            notifyItemRemoved(position)
            notifyDataSetChanged()
            XToast.warning(context,"文件不存在或不是文件类型!")
            return false;
        }
        return true;
    }

    override fun getItemCount(): Int {
        return scriptFileList.size
    }
}
